Skip to content

feat(runtime): sandbox security-opt / extra-binds / systempaths for e2e#2

Merged
matej21 merged 5 commits into
mainfrom
feat/security-opt
Jun 3, 2026
Merged

feat(runtime): sandbox security-opt / extra-binds / systempaths for e2e#2
matej21 merged 5 commits into
mainfrom
feat/security-opt

Conversation

@matej21

@matej21 matej21 commented Jun 3, 2026

Copy link
Copy Markdown
Member

Runtime knobs that let an in-sandbox agent (bubblewrap-based run_command) actually build inside an edvabe Docker sandbox, needed for the webmaster deterministic redo-flow e2e.

Changes

  • EDVABE_SECURITY_OPT — comma-separated list applied as HostConfig.SecurityOpt on every spawned sandbox (e.g. seccomp=unconfined,apparmor=unconfined).
  • EDVABE_EXTRA_BINDS — extra bind mounts (host:ctr[:ro]) on every sandbox, e.g. to share host LLM-replay fixtures.
  • systempaths=unconfined — recognized inside EDVABE_SECURITY_OPT and translated to empty MaskedPaths/ReadonlyPaths (same effect as docker run --security-opt systempaths=unconfined), rather than forwarded verbatim — the daemon rejects systempaths as a raw API-level SecurityOpt. Docker masks /proc/* by default, so without this bubblewrap fails with Can't mount proc on /newroot/proc: Operation not permitted.
  • stable sort of dashboard sandboxes/templates.

Why

On hosts with kernel.apparmor_restrict_unprivileged_userns=1 (Ubuntu 23.10+) plus Docker's default /proc masking, the agent's bwrap sandbox can't create a user namespace or mount a fresh /proc. All three opts (seccomp + apparmor + systempaths) are required for the in-sandbox build to run. Opt-in via env; each relaxes isolation, intended for local/e2e.

Tests

  • TestParseSecurityOpt covers the systempaths extraction, trimming, and case-insensitivity.
  • Verified end to end: spawned sandbox shows MaskedPaths: [], bwrap --proc /proc succeeds, and the webmaster redo e2e builds a real Astro site with 0 bwrap errors.

🤖 Generated with Claude Code

Go map iteration is randomized, so consecutive refreshes reshuffled
rows. Match the control plane ordering (CreatedAt asc, ID tiebreaker).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@matej21 matej21 force-pushed the feat/security-opt branch from b474428 to 480f941 Compare June 3, 2026 15:42
matej21 and others added 4 commits June 3, 2026 17:46
Lets operators set HostConfig.SecurityOpt (comma-separated) on every spawned
sandbox, e.g. seccomp=unconfined so in-sandbox bubblewrap can create user
namespaces. Opt-in; when set it replaces edvabe's default
(seccomp=unconfined, apparmor=unconfined), and when unset that default stays.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds extra bind mounts (comma-separated host:ctr[:ro]) to every spawned sandbox,
on top of per-request mounts. Lets the operator share host fixtures (e.g. LLM
replay snapshots) with sandboxes for deterministic local testing. Opt-in.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ReadonlyPaths

EDVABE_SECURITY_OPT now recognizes "systempaths=unconfined" and clears the
spawned sandbox's MaskedPaths/ReadonlyPaths (the same effect as `docker run
--security-opt systempaths=unconfined`), instead of forwarding it verbatim as a
SecurityOpt — which the daemon rejects, since systempaths is CLI sugar, not an
API-level opt.

Docker masks /proc/* by default, so in-sandbox bubblewrap fails to mount a fresh
/proc ("Can't mount proc on /newroot/proc: Operation not permitted"). Clearing
the masks lets the agent's run_command sandbox build. Opt-in; relaxes isolation.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@matej21 matej21 force-pushed the feat/security-opt branch from 480f941 to 2199b0d Compare June 3, 2026 15:50
@matej21 matej21 merged commit 3b52f51 into main Jun 3, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant